package com.mycompany.project.client.duch;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.http.client.URL;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONNumber;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.json.client.JSONString;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.ListBox;
import com.mycompany.project.client.ModuleType;
import com.mycompany.project.client.chee.LoadSaveModuleDetailGUI;
import com.mycompany.project.client.chee.Module;
import com.mycompany.project.client.chee.ModuleList;

/**
 * Class that will handle the NASA/ESA test feed.
 * @author Timothy
 */
public class Testing {
    /**
     * The list box containing the test cases.
     */
    private final transient ListBox testList;
    /**
     * The horizontal panel to contain the list box of test cases
     * and the button to test that case.
     */
    private final transient HorizontalPanel hPanel = new HorizontalPanel();
    /**
     * The proxy php file.
     */
    private static final transient String PROXY =
            "http://www.d.umn.edu/~duchx003/proxy.php?url=";
    /**
     * The url for the proxy to evaluate.
     */
    private transient String url;
    /**
     * Constructor for the Testing class.
     */
    public Testing() {
        testList = new ListBox();
        testList.addItem("Test 1");
        testList.addItem("Test 2");
        testList.addItem("Test 3");
        testList.addItem("Test 4");
        testList.addItem("Test 5");
        testList.setVisibleItemCount(1);
        Button testButton = new Button("Test Case");
        testButton.addClickHandler(new ClickHandler() {
            public void onClick(final ClickEvent event) {
                if (testList.getSelectedIndex() == 0) {
                    url = PROXY + "http://www.d.umn.edu"
                            + "/~abrooks/SomeTests.php?q=1";
                    url = URL.encode(url);
                    Window.alert(url); //TESTING: show the url to go to.
                    processTest();
                } else if (testList.getSelectedIndex() == 1) {
                    url = PROXY + "http://www.d.umn.edu"
                            + "/~abrooks/SomeTests.php?q=2";
                    url = URL.encode(url);
                    processTest();
                } else if (testList.getSelectedIndex() == 2) {
                    url = PROXY + "http://www.d.umn.edu"
                            + "/~abrooks/SomeTests.php?q=3";
                    url = URL.encode(url);
                    processTest();
                } else if (testList.getSelectedIndex() == 3) {
                    url = PROXY + "http://www.d.umn.edu"
                            + "/~abrooks/SomeTests.php?q=4";
                    url = URL.encode(url);
                    processTest();
                } else if (testList.getSelectedIndex() == 4) {
                    url = PROXY + "http://www.d.umn.edu"
                            + "/~abrooks/SomeTests.php?q=5";
                    url = URL.encode(url);
                    processTest();
                }
            }
        });
        hPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
        hPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
        hPanel.setSize("675px", "569px");
        hPanel.add(testList);
        hPanel.add(testButton);
    }
    /**
     * The action behind the testButton, that will process the test case.
     */
    private void processTest() {
        RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, url);
        try {
            @SuppressWarnings("unused")
            Request request = builder.sendRequest(null, new RequestCallback() {
                public void onError(
                        final Request request, final Throwable exception) {
                    Window.alert("onError: Couldn't Retrieve JSON");
                }
                public void onResponseReceived(
                        final Request request, final Response response) {
                    if (200 == response.getStatusCode()) {
                        String jsonString = response.getText();
                        update(jsonString);
                    } else {
                        Window.alert("Couldn't retrieve JSON ("
                    + response.getStatusText() + ")");
                    }
                }
            });
        } catch (RequestException e) {
            Window.alert("Request Exception: Couldn't retrieve JSON");
        }
    }
    /**
     * Will handle the actual JSON object and inputting into the module log.
     * @param jsonString is the string format of the JSON object.
     */
    private void update(final String jsonString) {
        //clearing the module log
        for (int i = 0; i < ModuleList.getMlist().size(); i++) {//clear list
            ModuleList.getMlist().get(i).clear();
        }
        String sAll = jsonString;
        //TESTING: Show the string being parsed.
        Window.alert("This is the string:\n" + jsonString);
        JSONArray jArray = (JSONArray) JSONParser.parseLenient(sAll);
        JSONNumber jNumber;
        JSONString jString;
        double numHolder;
        String stringHolder;
        //iterate through JSONArray and create modules
        for (int i = 0; i < jArray.size(); i++) {
            Module tempModule = new Module();
            JSONObject jObject = (JSONObject) jArray.get(i);
            jNumber = (JSONNumber) jObject.get("code");
            numHolder = jNumber.doubleValue();
            tempModule.setCodeNumber((int) numHolder); //set module code
            jString = (JSONString) jObject.get("status");
            stringHolder = jString.stringValue();
            if (stringHolder.equals("undamaged")) { //set module status
                tempModule.setStats("usable");
            } else if (stringHolder.equals("damaged")) {
                tempModule.setStats("beyond repair");
            }
            jNumber = (JSONNumber) jObject.get("turns");
            numHolder = jNumber.doubleValue();
            tempModule.setOrientation((int) numHolder); //set module orientation
            jNumber = (JSONNumber) jObject.get("X");
            numHolder = jNumber.doubleValue();
            tempModule.setPositionX((int) numHolder); //set module x coordinate
            jNumber = (JSONNumber) jObject.get("Y");
            numHolder = jNumber.doubleValue();
            tempModule.setPositionY((int) numHolder); //set module y coordinate
            
            //adding module to log
            if (tempModule.getCodeNumber() <= 40 && tempModule.getCodeNumber() >= 1) {//plain
                tempModule.setModuleType(ModuleType.PLAIN);
                ModuleList.addModule(tempModule);
            } else if (tempModule.getCodeNumber() <= 80 && tempModule.getCodeNumber() >= 61) {//dormitory
                tempModule.setModuleType(ModuleType.DORMITORY);
                ModuleList.addModule(tempModule);
            } else if (tempModule.getCodeNumber() <= 100 && tempModule.getCodeNumber() >= 91) {//sanitation
                tempModule.setModuleType(ModuleType.SANITATION);
                ModuleList.addModule(tempModule);
            } else if (tempModule.getCodeNumber() <= 120 && tempModule.getCodeNumber() >= 111) { //food&water
                tempModule.setModuleType(ModuleType.FOOD_WATER_STORAGE);
                ModuleList.addModule(tempModule);
            } else if (tempModule.getCodeNumber() <= 134 && tempModule.getCodeNumber() >= 131) { //gym
                tempModule.setModuleType(ModuleType.GYM_RELAXATION);
                ModuleList.addModule(tempModule);
            } else if (tempModule.getCodeNumber() <= 144 && tempModule.getCodeNumber() >= 141) { //canteen
                tempModule.setModuleType(ModuleType.CANTEEN);
                ModuleList.addModule(tempModule);
            } else if (tempModule.getCodeNumber() <= 154 && tempModule.getCodeNumber() >= 151) { //power
                tempModule.setModuleType(ModuleType.POWER);
                ModuleList.addModule(tempModule);
            } else if (tempModule.getCodeNumber() <= 164 && tempModule.getCodeNumber() >= 161) { //control
                tempModule.setModuleType(ModuleType.CONTROL);
                ModuleList.addModule(tempModule);
            } else if (tempModule.getCodeNumber() <= 174 && tempModule.getCodeNumber() >= 171) { //airlock
                tempModule.setModuleType(ModuleType.AIR_LOCK);
                ModuleList.addModule(tempModule);
            } else if (tempModule.getCodeNumber() <= 184 && tempModule.getCodeNumber() >= 181) { //medical
                tempModule.setModuleType(ModuleType.MEDICAL);
                ModuleList.addModule(tempModule);
            } //end if
            //set image url
            tempModule.setUrl(Module.getModuleImage(tempModule.getModuleType().ordinal()));
            LoadSaveModuleDetailGUI.saveToMem("TEST");
            LoadSaveModuleDetailGUI.loadFromMem("TEST");
        } //end for
    }
    /**
     * Returns the panel for embedding into the main frame. This panel
     * contains the list box for test cases and button to test that case.
     * @return hpanel is the panel containing the listbox and test button.
     */
    public final HorizontalPanel getHPanel() {
        return hPanel;
    }
}
